﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DBMS.Models;
using DBMS.Models.DataInterfaces;
using DBMS.Data;

namespace DBMS.Controllers
{
    public class ValuesController : Controller
    {
        private ITableRepository tableRepository;
        private IDatabaseRepository databaseRepository;
        private IColumnRepository columnRepository;
        private IValueRepository valueRepository;
        private IRelationshipRepository relationshipRepository;

        public ValuesController()
        {
            this.databaseRepository = new DatabaseRepository();
            this.tableRepository = new TableRepository();
            this.columnRepository = new ColumnRepository();
            this.valueRepository = new ValueRepository();
            this.relationshipRepository = new RelationshipRepository();
        }

        public ActionResult CreateValue(string databaseId, string tableId)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));

            Table table = tableRepository.GetTable(database.Index, Int32.Parse(tableId));

            ViewBag.Database = database;
            ViewBag.Table = table;

            return PartialView();
        }

        [HttpPost]
        public ActionResult CreateValue(string databaseId, string tableId, Value value)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));

            Table table = tableRepository.GetTable(database.Index, Int32.Parse(tableId));

            valueRepository.SaveOrUpdate(database.Index, table.Index, value);

            return RedirectToAction("BrowseTable", "Tables", new { databaseId = database.Index, tableId = table.Index });
        }

        [HttpPost]
        public ActionResult CreateValues(string databaseId, string tableId, IEnumerable<string> values)
        {
            int columnCount = columnRepository.GetAllColumnsForTable(Int32.Parse(databaseId), Int32.Parse(tableId)).Count();

            valueRepository.SaveMultipleValues(Int32.Parse(databaseId), Int32.Parse(tableId), columnCount, values);

            return RedirectToAction("BrowseTable", "Tables", new { databaseId = databaseId, tableId = tableId });
        }

        public ActionResult EditValues(string databaseId, string tableId, IEnumerable<string> values)
        {
            int columnCount = columnRepository.GetAllColumnsForTable(Int32.Parse(databaseId), Int32.Parse(tableId)).Count();

            return View();
        }

        public ActionResult EditRow(string databaseId, string tableId, string rowId)
        {
            Database database = databaseRepository.GetDatabase(Int32.Parse(databaseId));
            Table table = tableRepository.GetTable(database.Index, Int32.Parse(tableId));

            List<Column> columns = columnRepository.GetAllColumnsForTable(Int32.Parse(databaseId), Int32.Parse(tableId)).ToList();

            List<Value> values = valueRepository.GetValuesForTable(Int32.Parse(databaseId), Int32.Parse(tableId)).Where(x => x.RowId == Int32.Parse(rowId)).ToList();

            ViewBag.Database = database;
            ViewBag.RowId = rowId;
            ViewBag.Columns = columns;
            ViewBag.Values = values;
            ViewBag.Table = table;

            return View();
        }

        [HttpPost]
        public ActionResult EditRow(string databaseId, string tableId, string rowId, IEnumerable<string> values)
        {
            valueRepository.UpdateMultipleValues(Int32.Parse(databaseId), Int32.Parse(tableId), Int32.Parse(rowId), values);

            return RedirectToAction("BrowseTable", "Tables", new { databaseId = databaseId, tableId = tableId });
        }

        public ActionResult DeactivateValue(string databaseId, string tableId, string valueId)
        {
            return RedirectToAction("BrowseTable", "Tables", new { databaseId = databaseId, tableId = tableId });
        }

        public ActionResult Menu()
        {
            return PartialView();
        }

        public ActionResult DeleteRow(string databaseId, string tableId, string rowId)
        {
            IList<Relationship> relationships = relationshipRepository.GetAllRelationshipsForDatabase(Int32.Parse(databaseId));

            foreach (Relationship relationship in relationships)
            {
                if (relationship.PrimaryTableId == Int32.Parse(tableId))
                {
                    IList<Value> primvalues = valueRepository.GetValuesForColumn(Int32.Parse(databaseId), relationship.PrimaryTableId, relationship.PrimaryColumnId);

                    Value value = primvalues.Single(x => x.RowId == Int32.Parse(rowId));

                    IList<Value> values = valueRepository.GetValuesForColumn(Int32.Parse(databaseId), relationship.ForeignTableId, relationship.ForeignColumnId);

                    if (values.Count > 0)
                    {
                        IList<string> concreteValues = values.Select(x => x.ConcreteValue).ToList();

                        if (concreteValues.Contains(value.ConcreteValue))
                        {
                            ViewBag.ErrorMessage = "FK_CONSTRAINT Violation!";

                            return RedirectToAction("BrowseTable", "Tables", new { databaseId = databaseId, tableId = tableId });
                        }
                    }
                }
            }

            valueRepository.DeleteRow(Int32.Parse(databaseId), Int32.Parse(tableId), Int32.Parse(rowId));   

            return RedirectToAction("BrowseTable", "Tables", new { databaseId = databaseId, tableId = tableId });
        }

    }
}
